home *** CD-ROM | disk | FTP | other *** search
- ;/*
- gcc -m68020-60 -noixemul -nostdlib -nostartfiles -msmall-code -O2 -fstrength-reduce -fomit-frame-pointer -mregparm=3 -s move.c -o c:move
- shortrel c:move
- protect c:move p add
- quit
- */
-
- /*
- **
- ** Move.c - (C) 1993-99 by Stephan Rupprecht
- ** a move command for AmigaDOS
- **
- */
-
- #include <dos/dos.h>
- #include <dos/dosasl.h>
- #include <dos/dosextens.h>
- #include <exec/execbase.h>
-
- #include <proto/dos.h>
- #include <proto/exec.h>
-
- #define FULLPATHSIZE 256
- #define REG(reg,arg) arg __asm(#reg)
-
- /****************************************************************************/
-
- struct args {
- STRPTR *src, dst;
- LONG as;
- LONG noreq;
- LONG force;
- LONG skip;
- LONG *buffer;
- LONG quiet;
- };
-
- /****************************************************************************/
-
- LONG start( void );
- LONG CopyFile( struct FileInfoBlock *fib, const STRPTR to, ULONG bufsize, const struct args *args, STRPTR *move_text, REG( a6, const struct Library *DOSBase ) );
- LONG Delete( struct FileInfoBlock *fib, REG( a6, const struct Library *DOSBase ) );
- LONG CheckLoop( const STRPTR name, BPTR parent, REG( a6, const struct Library *DOSBase ) );
- void StrnCpy( STRPTR a, STRPTR b, REG( d1, WORD c ) );
-
- /****************************************************************************/
-
- LONG dummy( void )
- {
- return start();
- }
-
- /****************************************************************************/
-
- LONG start( void )
- {
- const STRPTR VerStr = "$VER: move 37.6 (30.10.99) © 1997-99 by Stephan Rupprecht";
- struct Library *SysBase = (*(struct Library **)4L);
- struct Library *DOSBase;
- LONG error = 0L;
-
- if( DOSBase = OpenLibrary( "dos.library", 37L ) )
- {
- struct args args = {};
- struct RDArgs *rdargs;
-
- if( rdargs = ReadArgs( "FROM/A/M,TO/A,AS/S,NOREQ/S,FORCE/S,SKIP/S,BUF=BUFFER/N/K,QUIET/S", (LONG *)&args, NULL ) )
- {
- struct AnchorPath *ap;
- struct Process *pr;
- APTR win;
- TEXT to[ FULLPATHSIZE ];
-
- if( args.noreq )
- {
- pr = (struct Process *) FindTask( NULL );
- win = pr->pr_WindowPtr;
- pr->pr_WindowPtr = (APTR) ~0L;
- }
-
- for( ;; )
- {
- struct InfoData *id;
- ULONG bufsize;
-
- if( args.force && ( args.as || args.skip ) )
- {
- Printf( "FORCE can't be used in conjunction with AS or SKIP!\n" );
- break;
- }
-
- if( ! GetCurrentDirName( to, sizeof( to ) ) ||
- ! AddPart( to, args.dst, sizeof( to ) ) )
- {
- error = IoErr();
- break;
- }
-
- if( id = AllocMem( sizeof( *id ), MEMF_PUBLIC ) )
- {
- ULONG tmp, bpp = 512L;
- TEXT buf[ FULLPATHSIZE ];
-
- tmp = (args.as) ? ( (ULONG) PathPart( to ) - (ULONG) to ) : sizeof( buf );
- StrnCpy( buf, to, tmp );
-
- if( ! ( tmp = Lock( buf, SHARED_LOCK ) ) )
- {
- if( ! ( tmp = CreateDir( buf ) ) )
- {
- error = IoErr();
- break;
- }
- else if( ! args.quiet )
- {
- Printf( "Directory %s created.\n", (ULONG) buf );
- }
- }
-
- if( Info( tmp, id ) )
- {
- bpp = id->id_BytesPerBlock;
- }
-
- bufsize = ( bpp * ( ( args.buffer ) ? *args.buffer : 200L ) ) / 2L;
-
- UnLock( tmp );
-
- FreeMem( id, sizeof( *id ) );
- }
- else
- {
- error = ERROR_NO_FREE_STORE;
- break;
- }
-
- if( ap = AllocMem( sizeof( *ap ) + FULLPATHSIZE, MEMF_CLEAR|MEMF_PUBLIC ) )
- {
- ap->ap_BreakBits = SIGBREAKF_CTRL_C;
- ap->ap_Strlen = FULLPATHSIZE;
- ap->ap_Flags = APF_FollowHLinks;
-
- while( *args.src )
- {
- LONG depth = 0L;
-
- error = MatchFirst( *args.src, ap );
-
- while( ! error )
- {
- STRPTR from = ap->ap_Info.fib_FileName,
- move_text = "moved.\n";
- BPTR lock = ap->ap_Current->an_Lock, cd;
- LONG type = ap->ap_Info.fib_DirEntryType;
- BOOL releaselock = FALSE;
-
- if( *from == '\0' )
- {
- StrnCpy( from, FilePart( ap->ap_Buf ), 108L );
-
- if( ! ( lock = ParentDir( lock ) ) )
- {
- if( ! ( error = IoErr() ) )
- {
- error = ERROR_OBJECT_WRONG_TYPE;
- }
- }
-
- releaselock = TRUE;
- }
-
- cd = CurrentDir( lock );
-
- if( ap->ap_Flags & APF_DIDDIR )
- {
- ap->ap_Flags &= ~APF_DIDDIR;
-
- if( ! ( ! --depth && args.as ) )
- {
- *PathPart( to ) = '\0';
- }
-
- error = Delete( &ap->ap_Info, DOSBase );
- }
- else
- {
- if( ! ( args.as && ! depth ) )
- {
- if( ! AddPart( to, from, sizeof( to ) ) )
- {
- error = ERROR_BUFFER_OVERFLOW;
- }
- }
-
- #ifdef DEBUG
- {
- TEXT buf[ 256 ];
-
- NameFromLock( lock, buf, sizeof( buf ) );
- AddPart( buf, from, sizeof( buf ) );
-
- Printf( "ap->ap_Buf: %s\n"
- "AddPart(ed): %s -> %s (%ld)\n",
- ap->ap_Buf, buf, to, type );
-
- args.quiet = TRUE;
- }
- #endif
-
- if( ! error )
- {
- BOOL dodir = ( type >= 0L );
-
- if( type == ST_SOFTLINK )
- {
- BPTR fh;
-
- if( fh = Open( from, MODE_OLDFILE ) )
- {
- Close( fh );
- dodir = FALSE;
- }
- else if( ( error = IoErr() ) == ERROR_OBJECT_WRONG_TYPE )
- {
- error = 0L;
- }
- }
-
- if( ! args.quiet )
- {
- LONG i;
-
- for( i = depth+1; i; i-- )
- {
- Printf( " " );
- }
-
- Printf( dodir ? " %s (Dir)" : " %s..", (ULONG) from );
- Flush( Output() );
- }
-
- if( ! error )
- {
- if( ! Rename( from, to ) && ( ( error = IoErr() ) == ERROR_RENAME_ACROSS_DEVICES ) )
- {
- error = 0L;
-
- for( ;; )
- {
- if( dodir )
- {
- BPTR fl;
-
- move_text = "\n";
-
- depth++;
-
- ap->ap_Flags |= APF_DODIR;
-
- if( type == ST_SOFTLINK || type == ST_LINKDIR )
- {
- if( error = CheckLoop( from, lock, DOSBase ) )
- {
- break;
- }
- }
-
- if( fl = CreateDir( to ) )
- {
- if( ! args.quiet )
- {
- Printf( " [created]" );
- }
-
- UnLock( fl );
- }
- else if( ( error = IoErr() ) == ERROR_OBJECT_EXISTS )
- {
- error = 0L;
- }
- }
- else
- {
- if( ! ( error = CopyFile( &ap->ap_Info, to, bufsize, &args, &move_text, DOSBase ) ) )
- {
- error = Delete( &ap->ap_Info, DOSBase );
- }
-
- if( ! ( args.as && ! depth ) )
- {
- *PathPart( to ) = '\0';
- }
- }
-
- break;
- }
- }
- else
- {
- if( error == ERROR_OBJECT_EXISTS )
- {
- if( args.skip )
- {
- error = 0L;
- move_text = "skipped.\n";
- }
- else if( args.force )
- {
- SetProtection( to, ~(FIBF_DELETE|FIBF_OTR_DELETE) );
-
- if( DeleteFile( to ) && Rename( from, to ) )
- {
- error = 0L;
- }
- }
- }
-
- if( ! ( args.as && ! depth ) )
- {
- *PathPart( to ) = '\0';
- }
- }
- }
-
- if( ! args.quiet )
- {
- Printf( error ? "failed.\n" : move_text );
- }
- }
-
- if( error )
- {
- Printf( "Can't move %s\n", (ULONG) ap->ap_Buf );
- }
- }
-
- CurrentDir( cd );
-
- if( releaselock )
- {
- UnLock( lock );
- *from = '\0';
- }
-
- if( ! error )
- {
- error = MatchNext( ap );
- }
- }
-
- MatchEnd( ap );
-
- if( error == ERROR_NO_MORE_ENTRIES )
- {
- error = 0L;
- }
-
- if( error )
- {
- break;
- }
-
- args.src++;
- }
-
- FreeMem( ap, sizeof( *ap ) + FULLPATHSIZE );
- }
- else
- {
- error = ERROR_NO_FREE_STORE;
- }
-
- break;
- }
-
- if( args.noreq )
- {
- pr->pr_WindowPtr = win;
- }
-
- FreeArgs( rdargs );
- }
- else
- {
- error = IoErr();
- }
-
- PrintFault( error, "Move" );
-
- CloseLibrary( DOSBase );
- }
-
- return( error ? RETURN_ERROR : RETURN_OK );
- }
-
- /****************************************************************************/
-
- LONG CopyFile( struct FileInfoBlock *fib, const STRPTR to, ULONG bufsize, const struct args *args, STRPTR *move_text, REG( a6, const struct Library *DOSBase ) )
- {
- BPTR fhin, fhout;
- LONG err = 0L;
-
- if( fhin = Lock( to, SHARED_LOCK ) )
- {
- UnLock( fhin );
-
- if( args->skip )
- {
- *move_text = "skipped.\n";
- return 0L;
- }
- else if( args->force )
- {
- SetProtection( to, ~(FIBF_OTR_WRITE|FIBF_OTR_DELETE|FIBF_WRITE|FIBF_DELETE) );
- }
- else
- {
- return ERROR_OBJECT_EXISTS;
- }
- }
-
- if( fhout = Open( fib->fib_FileName, MODE_OLDFILE ) )
- {
- if( fhin = Open( to, MODE_NEWFILE ) )
- {
- if( fib->fib_Size )
- {
- struct Library *SysBase = (*(struct Library **)4L);
- UBYTE *buf[ 2 ], *buffer;
- ULONG allocsize;
-
- err = ERROR_NO_FREE_STORE;
-
- if( bufsize == 0 || fib->fib_Size < bufsize )
- {
- bufsize = fib->fib_Size;
- allocsize = bufsize;
- }
- else
- {
- allocsize = ( bufsize * 2 );
- }
-
- while( ! ( buffer = AllocMem( allocsize + 15L, MEMF_PUBLIC ) ) )
- {
- bufsize /= 2;
-
- if( ( allocsize = bufsize * 2 ) < 8192L )
- {
- break;
- }
- }
-
- if( buffer )
- {
- struct DosPacket *rdp, *wdp;
-
- buf[ 0 ] = (UBYTE *) (((ULONG)buffer + 15L)&0xfffffff0);
- buf[ 1 ] = buf[ 0 ] + bufsize;
-
- if( rdp = AllocDosObject( DOS_STDPKT, NULL ) )
- {
- if( wdp = AllocDosObject( DOS_STDPKT, NULL ) )
- {
- struct MsgPort *rmp = (struct MsgPort *) ((struct FileHandle *)BADDR( fhout ))->fh_Type,
- *wmp = (struct MsgPort *) ((struct FileHandle *)BADDR( fhin ))->fh_Type,
- *replyport = &((struct Process *)FindTask( NULL ))->pr_MsgPort;
- LONG index = 0, rres1;
- BOOL first = TRUE, samedev = FALSE;
- /*
- ** try to determine if source and dest are on the
- ** same physical device
- */
- {
- BPTR l1, l2;
-
- if( l1 = DupLockFromFH( fhout ) )
- {
- if( l2 = ParentOfFH( fhin ) )
- {
- samedev = SameDevice( l1, l2 );
- UnLock( l2 );
- }
-
- UnLock( l1 );
- }
- }
-
- rdp->dp_Type = ACTION_READ;
- rdp->dp_Arg1 = ((struct FileHandle *)BADDR( fhout ))->fh_Arg1;
- rdp->dp_Arg3 = samedev ? bufsize*2 : bufsize;
-
- wdp->dp_Type = ACTION_WRITE;
- wdp->dp_Arg1 = ((struct FileHandle *)BADDR( fhin ))->fh_Arg1;
-
- for( ;; )
- {
- rdp->dp_Arg2 = (LONG) buf[ index ];
- SendPkt( rdp, rmp, replyport );
-
- if( ! first )
- {
- WaitPkt();
- }
-
- WaitPkt();
-
- if( (rres1 = rdp->dp_Res1) <= 0 )
- {
- err = rdp->dp_Res2;
- break;
- }
-
- if( ! first && wdp->dp_Res1 != wdp->dp_Arg3 )
- {
- err = wdp->dp_Res2;
- break;
- }
-
- if( CheckSignal( SIGBREAKF_CTRL_C ) )
- {
- err = ERROR_BREAK;
- break;
- }
-
- wdp->dp_Arg2 = (LONG) buf[ index ];
- wdp->dp_Arg3 = rres1;
- SendPkt( wdp, wmp, replyport );
-
- if( samedev )
- {
- WaitPkt();
-
- if( wdp->dp_Res1 != wdp->dp_Arg3 )
- {
- err = wdp->dp_Res2;
- break;
- }
- }
- else
- {
- index ^= 1;
- first = FALSE;
- }
- }
-
- FreeDosObject( DOS_STDPKT, wdp );
- }
-
- FreeDosObject( DOS_STDPKT, rdp );
- }
-
- FreeMem( buffer, allocsize + 15L );
- }
- }
-
- Close( fhin );
-
- if( err )
- {
- DeleteFile( to );
- }
- else
- {
- SetComment( to, fib->fib_Comment );
- SetProtection( to, fib->fib_Protection );
- SetFileDate( to, &fib->fib_Date );
- }
- }
- else
- {
- err = IoErr();
- }
-
- Close( fhout );
- }
- else
- {
- err = IoErr();
- }
-
- return( err );
- }
-
- /****************************************************************************/
-
- LONG Delete( struct FileInfoBlock *fib, REG( a6, const struct Library *DOSBase ) )
- {
- if( fib->fib_Protection & (FIBF_DELETE|FIBF_OTR_DELETE) )
- {
- SetProtection( fib->fib_FileName, fib->fib_Protection & ~(FIBF_DELETE|FIBF_OTR_DELETE) );
- }
-
- DeleteFile( fib->fib_FileName );
-
- return IoErr();
- }
-
- /****************************************************************************/
-
- LONG CheckLoop( const STRPTR name, BPTR parent, REG( a6, const struct Library *DOSBase ) )
- {
- BPTR cmp, prev = 0L;
- LONG err = 0L;
-
- if( cmp = Lock( name, SHARED_LOCK ) )
- {
- do
- {
- if( SameLock( cmp, parent ) )
- {
- parent = ParentDir( parent );
- }
- else
- {
- err = ERROR_OBJECT_LINKED;
- parent = 0L;
- }
-
- UnLock( prev );
- prev = parent;
- }
- while( parent );
-
- UnLock( cmp );
- }
- else
- {
- err = IoErr();
- }
-
- return err;
- }
-
- /****************************************************************************/
-
- void StrnCpy( STRPTR a, STRPTR b, REG( d1, WORD c ) )
- {
- do
- {
- if( ! ( *a++ = *b++ ) ) return;
- }
- while( --c );
-
- *a = '\0';
- }
-
- /****************************************************************************/
-